#ifndef ISOFORMSENUMERATOR_H
#define ISOFORMSENUMERATOR_H
#include "stdafx.h"
#include "Isoform.h"
#include "Junctions.h"
#include "ProteinFrame.h"
#include "outputIsoforms.h"
#include "ShortReadUtil.h"
#include "Filename.h"
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <limits>
#include <set>
using namespace std;

const int MIN_FRAME_SCORE = 3;

class CIsoformsEnumerator
{
public:
    CIsoformsEnumerator(int geneStart, int geneEnd, bool forward, CJunctions* js, CJunctions* ocean = NULL);
    ~CIsoformsEnumerator(void);
    int enumerateIsoforms(int maxExons);
    int enumerateIsoforms(int pos, int maxExons, int maxLength);
    void sortJunctions_oceans(void); // sort ocean and juncitons according to forward flag;
    void clear(void); // clear enumerated isoforms
    CJunctions* bridges;    // the splicing junction (Bridge)
    CJunctions* ocean; // the regions that is no expressed
    CTIsoform isoform; // the current enumerated isoform
    vector<CTIsoform> isoforms; // vector to store all isoform
    int geneStart;
    int geneEnd;
    bool forward;
private:
    // add the last exon and save into record
    int addLastExon(int start, int end);
    int nextBeach(int pos);
    set<string> IsoformsKey;
};
string isoformTag(CTIsoform& isoform); // return a string as the tag of isoform
vector<int> getPossibleIsoformStarts(int initialStart, CJunctions& bridges, CJunctions& oceans);
// filter and print the NT seqeunce of the given isforom is valid. Return false if it is not printed.
CIsoformInfo getIsoformInfo(string geneName, const char* isoformID, const char* contig, CTIsoform& isoform);
// Get the coding sequences set from isoforms.
set<string> getCDSs(vector<CTIsoform>& isoforms, const char* contig);
// called by reportIsoform to filter the short Isoform. Return true is pass the filtering.
bool filterIsoform(CIsoformInfo& isoformInfo);
// const int MIN_ISOFORM_LENGTH = 300;
// test
bool testCIsoformsEnumerator(void);
bool testPossibleStartSites(void);
#endif
